﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using l1cs.server.model;
using l1cs.server.model.Instance;
using l1cs.server.model.npc;
using l1cs.server.model.npc.action;
using l1cs.server.server.utils;
using System.Data;
using System.Collections;

namespace l1cs.server.datatables
{
    public class NpcActionTable
    {
        private static Logger _log = Logger.getLogger( typeof( NpcActionTable ).FullName );

        private static NpcActionTable _instance;

        private List<L1NpcAction> _actions = new List<L1NpcAction>();

        private List<L1NpcAction> _talkActions = new List<L1NpcAction>();

        private List<L1NpcAction> loadAction( string file, String nodeName )
        {
            // 「XmlReader」インスタンスの宣言(nullで初期化)
            XmlReader reader = null;
            // 特別なルールを設定する場合、「XmlReaderSettings」クラスを使用する。
            XmlReaderSettings settings = new XmlReaderSettings();
            // 検証は「整形式かどうか」の検査のみ
            settings.ConformanceLevel = ConformanceLevel.Document;

            // 「XmlReader」の作成
            reader = XmlReader.Create( file, settings );

            List<L1NpcAction> result = null;
            while ( reader.Read() )
            {
                // 開始タグを発見した場合
                if ( reader.NodeType == XmlNodeType.Element )
                {
                    //_log.info( "開始タグ : {0} (深さ : {1})", reader.LocalName, reader.Depth );
                    if ( reader.Depth == 0 )
                    {
                        if ( string.Compare( reader.LocalName, nodeName, true ) != 0 )
                        {
                            result = new List<L1NpcAction>();
                            break;
                        }
                        else
                        {
                            result = L1NpcXmlParser.listActions( reader );
                            break;
                        }
                    }
                }
            }
            return result;
        }

        private void loadAction( string file )
        {
            _actions.AddRange( loadAction( file, "NpcActionList" ) );
        }

        private void loadTalkAction( string file )
        {
            _talkActions.AddRange( loadAction( file, "NpcTalkActionList" ) );
        }

        private void loadDirectoryActions( String dir )
        {
            string[] files = Directory.GetFiles( dir, "*.xml", SearchOption.AllDirectories );
            foreach ( string file in files )
            {
                loadAction( file );
                loadTalkAction( file );
            }
        }

        private NpcActionTable()
        {
            PerformanceTimer timer = new PerformanceTimer();
            _log.info( "loading npcaction..." );
            string usersDir = "./data/xml/NpcActions/users/";
            if ( Directory.Exists( usersDir ) )
            {
                loadDirectoryActions( usersDir );
            }
            loadDirectoryActions( "./data/xml/NpcActions/" );
            _log.info( "OK! " + timer.get() + "ms" );
        }

        public static NpcActionTable getInstance()
        {
            if ( _instance == null )
            {
                _instance = new NpcActionTable();
            }
            return _instance;
        }

        public L1NpcAction get( String actionName, L1PcInstance pc, L1Object obj )
        {
            foreach ( L1NpcAction action in _actions )
            {
                if ( action.acceptsRequest( actionName, pc, obj ) )
                {
                    return action;
                }
            }
            return null;
        }

        public L1NpcAction get( L1PcInstance pc, L1Object obj )
        {
            foreach ( L1NpcAction action in _talkActions )
            {
                if ( action.acceptsRequest( "", pc, obj ) )
                {
                    return action;
                }
            }
            return null;
        }
    }
}
